using System;
using Microsoft.SPOT;

namespace N2Plus_GPS
{
    /// <summary>
    /// Class to calculate time passed
    /// </summary>
    public class Stopwatch
    {
        #region Constants
        private const long _TicksPerMillisecond = System.TimeSpan.TicksPerMillisecond;
        #endregion

        #region Private variables
        /// <summary>
        /// The Start Ticks when initiated
        /// </summary>
        private long _StartTicks = 0;
        /// <summary>
        /// The Stop Ticks used to calculate time
        /// </summary>
        private long _StopTicks = 0;
        /// <summary>
        /// Whether stopwatch is running or not
        /// </summary>
        private bool _IsRunning = false;
        #endregion

        #region Constructors
        /// <summary>
        /// Default Constructor
        /// </summary>
        public Stopwatch()
        {
        }
        #endregion

        #region Properties
        private int _ElaspedMilliseconds = 0;
        /// <summary>
        /// The elapsed milliseconds of the stopwatch
        /// </summary>
        public int ElapsedMilliseconds
        {
            get
            {
                CalculateElapsedMilliseconds();
                return _ElaspedMilliseconds;
            }
        }

        private TimeSpan _Elapsed = default(TimeSpan);
        /// <summary>
        /// The timespan that was elapsed
        /// </summary>
        public TimeSpan Elapsed
        {
            get { return _Elapsed; }
        }
        #endregion

        #region Methods
        #region Public
        /// <summary>
        /// Starts the stopwatch
        /// </summary>
        public void Start()
        {
            if (_StartTicks != 0 && _StopTicks != 0)
                _StartTicks = Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks - (_StopTicks - _StartTicks); // resume existing timer
            else
                _StartTicks = Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks; // start new timer
            _IsRunning = true;
        }
        /// <summary>
        /// Stops the stopwatch
        /// </summary>
        public void Stop()
        {
            _StopTicks = Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks;
            _IsRunning = false;
        }
        /// <summary>
        /// Resets the stopwatch
        /// </summary>
        public void Reset()
        {
            _StartTicks = 0;
            _StopTicks = 0;
            _IsRunning = false;
        }
        #endregion

        #region Private
        /// <summary>
        /// Calculate the elapsed time to a Timespan Object
        /// </summary>
        private void CalculateElapsed()
        {
            CalculateElapsedMilliseconds();

            _Elapsed = new TimeSpan(0, 0, 0, 0, _ElaspedMilliseconds);
        }
        /// <summary>
        /// Calculate the elapsed time to milliseconds
        /// </summary>
        private void CalculateElapsedMilliseconds()
        {
            if (_StartTicks != 0 && _IsRunning)
                _ElaspedMilliseconds = (int)((Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks - _StartTicks) / _TicksPerMillisecond);
            else if (_StartTicks != 0 && !_IsRunning)
                _ElaspedMilliseconds = (int)((_StopTicks - _StartTicks) / _TicksPerMillisecond);
            else
                throw new InvalidOperationException();
        }
        #endregion
        #endregion








    }
}
